import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, mean_squared_error
from sklearn.cluster import KMeans

from wordcloud import WordCloud
import matplotlib.pyplot as plt
import seaborn as sns

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.metrics import accuracy_score, mean_squared_error
# 1. 数据清洗和预处理
data = pd.read_csv('./data/数据分析/marketing_campaign.csv')

# 定义数值特征和类别特征
numeric_features = ['Year_Birth', 'Income', 'Kidhome', 'Teenhome', 'Recency',
                    'MntWines', 'MntFruits', 'MntMeatProducts', 'MntFishProducts',
                    'MntSweetProducts', 'MntGoldProds', 'NumDealsPurchases',
                    'NumWebPurchases', 'NumCatalogPurchases', 'NumStorePurchases',
                    'NumWebVisitsMonth']
categorical_features = ['Education', 'Marital_Status']
# 处理缺失值
data[numeric_features] = data[numeric_features].fillna(data[numeric_features].mean())
data = data.dropna(subset=categorical_features)
# 数据类型转换和特征编码
preprocessor = ColumnTransformer(
    transformers=[
        ('num', StandardScaler(), numeric_features),
        ('cat', OneHotEncoder(), categorical_features)
    ]
)
# 2. 特征工程和模型训练
X = data.drop(['ID', 'Response'], axis=1)
y = data['Response']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义模型
models = {
    'RandomForest': RandomForestClassifier(random_state=42),
    'LogisticRegression': LogisticRegression(max_iter=1000)
}
pipelines = {}
for name, model in models.items():
    pipelines[name] = Pipeline([
        ('preprocessor', preprocessor),
        ('classifier', model)
    ])
# 训练模型
for name, pipeline in pipelines.items():
    pipeline.fit(X_train, y_train)
# 3. 模型评估与对比
for name, pipeline in pipelines.items():
    y_pred = pipeline.predict(X_test)
    print(f'{name} Accuracy: {accuracy_score(y_test, y_pred)}')
# 4. 利用客户的购买历史等特征分析购买偏好（此部分需要具体的数据分析代码，这里仅提供思路）
# 可以通过分析MntWines, MntFruits等购买金额特征与Response的关系，或者使用聚类算法对客户进行分群。
# 5. 构建客户价值评分模型
# 使用随机森林回归模型预测客户的总购买金额，并作为客户价值的评分依据。
# 首先，计算每个客户的总购买金额作为目标变量。
data['TotalPurchase'] = data['MntWines'] + data['MntFruits'] + data['MntMeatProducts'] + data['MntFishProducts'] + data['MntSweetProducts'] + data['MntGoldProds']
# 划分特征和目标变量
X_value = data.drop(['ID', 'Response', 'TotalPurchase'], axis=1)
y_value = data['TotalPurchase']
# 划分训练集和测试集
X_train_value, X_test_value, y_train_value, y_test_value = train_test_split(X_value, y_value, test_size=0.2, random_state=42)
# 定义随机森林回归模型
value_model = RandomForestRegressor(random_state=42)
# 创建预处理和模型的管道
pipeline_value = Pipeline([
    ('preprocessor', preprocessor),
    ('regressor', value_model)
])
# 训练模型
pipeline_value.fit(X_train_value, y_train_value)
# 预测测试集并评估模型
y_pred_value = pipeline_value.predict(X_test_value)
mse = mean_squared_error(y_test_value, y_pred_value)
print(f'Customer Value Model MSE: {mse}')
# 特征工程和模型训练
X = data.drop(['ID', 'Response'], axis=1)
y = data['Response']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义模型，加入线性回归 LinearRegression
models = {
    'RandomForest': RandomForestClassifier(random_state=42),
    'LogisticRegression': LogisticRegression(max_iter=1000),
    'LinearRegression': LogisticRegression(max_iter=1000)  # 这里暂时用LogisticRegression代替，仅作示意
}
# 为线性回归模型创建单独的管道，因为线性回归是回归模型，不适用于分类任务
regression_model = LinearRegression()
regression_pipeline = Pipeline([
    ('preprocessor', preprocessor),
    ('regressor', regression_model)
])
# 分类模型的管道
pipelines = {}
for name, model in models.items():
    if name != 'LinearRegression':  # 排除线性回归模型，因为它不是分类器
        pipelines[name] = Pipeline([
            ('preprocessor', preprocessor),
            ('classifier', model)
        ])
    # 训练分类模型
for name, pipeline in pipelines.items():
    pipeline.fit(X_train, y_train)
# 训练线性回归模型（这里需要使用适合回归任务的目标变量）
# 假设我们使用 'TotalPurchase' 作为回归任务的目标
y_reg = data['TotalPurchase']
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X, y_reg, test_size=0.2, random_state=42)
regression_pipeline.fit(X_train_reg, y_train_reg)
# 模型评估与对比（分类模型）
for name, pipeline in pipelines.items():
    y_pred = pipeline.predict(X_test)
    print(f'{name} Accuracy: {accuracy_score(y_test, y_pred)}')
# 评估线性回归模型
y_pred_reg = regression_pipeline.predict(X_test_reg)
mse_reg = mean_squared_error(y_test_reg, y_pred_reg)
print(f'Linear Regression MSE: {mse_reg}')

# ...（省略了部分代码，包括利用购买历史分析购买偏好和构建客户价值评分模型）

# # 利用客户的购买历史等特征分析购买偏好
# # 使用柱状图展示客户对不同产品的购买情况
plt.figure(figsize=(12, 6))
products = ['MntWines', 'MntFruits', 'MntMeatProducts', 'MntFishProducts', 'MntSweetProducts', 'MntGoldProds']
data[products].mean().plot(kind='bar')
plt.title('Average Purchase Amount of Different Products')
plt.xlabel('Products')
plt.ylabel('Average Purchase Amount')
plt.show()
#
# # 使用词云图展示购买金额最高的产品
text = ' '.join([f"{product}:{round(value,2)}" for product, value in data[products].mean().items()])
# wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
# plt.figure(figsize=(10, 8))
# plt.imshow(wordcloud, interpolation='bilinear')
# plt.axis('off')
# plt.show()
#
# # 构建客户价值评分模型部分保持不变...
#
# # 客户价值评分的可视化
y_pred_value = pipeline_value.predict(X_test_value)  # 修正了原代码中的错误（y_pred_value = pipeline_value.pr）
plt.figure(figsize=(10, 6))
sns.histplot(y_pred_value, kde=True, color='blue')
plt.title('Distribution of Customer Value Scores')
plt.xlabel('Customer Value Score')
plt.ylabel('Frequency')
plt.show()


# 假设我们有一个文本列，比如'CustomerComment'，我们想生成一个词云图
# 这里我们使用'CustomerComment'列生成词云，你可能需要根据你的数据集进行调整
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()

# 对于分类模型的评估结果，我们可以使用条形图进行可视化
plt.figure(figsize=(10, 6))
accuracies = {name: accuracy_score(y_test, pipeline.predict(X_test)) for name, pipeline in pipelines.items()}
sns.barplot(x=list(accuracies.keys()), y=list(accuracies.values()), order=sorted(accuracies, key=accuracies.get, reverse=True))
plt.title('Model Accuracies')
plt.xlabel('Model')
plt.ylabel('Accuracy')
plt.show()

# 对于回归模型，我们可以绘制预测值和实际值的散点图以及回归线
plt.figure(figsize=(10, 6))
sns.regplot(x=y_test_reg, y=y_pred_reg, scatter_kws={"s": 80})
plt.title('Actual vs Predicted Total Purchase')
plt.xlabel('Actual Total Purchase')
plt.ylabel('Predicted Total Purchase')
plt.show()



